﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml;
using System.Drawing.Design;
using EnvDTE;
using System.Windows.Forms;
using SPVisualDev.Services;
using System.Reflection;

namespace SPVisualDev.VSAddin.Dialogs.PropertySheets
{
    internal class PropSheetContentType : PropSheetBase
    {
        public PropSheetContentType(string DefaultResourceFile, EnvDTE.ProjectItem ParentFeatureFolder, ElementInfo Element, SpecialProject project)
        {
            this.Project = project;

            this.DefaultResourceFile = DefaultResourceFile;
            this.ParentFeatureFolder = ParentFeatureFolder;

            this.Name = new ResourceStringContainer(string.Empty, DefaultResourceFile, ParentFeatureFolder);
            this.Group = new ResourceStringContainer(string.Empty, DefaultResourceFile, ParentFeatureFolder);
            this.Description = new ResourceStringContainer(string.Empty, DefaultResourceFile, ParentFeatureFolder);

            this.ElementInfo = Element;

            this.ElementFileName = Element.ElementFileName;
            this.EventRegistrations = Element.EventReceivers;
            this.EventReceiverClasses = Element.AttachedEventReceiverClasses;

            if (Element.XmlElementNode != null)
                this.PropXmlNode = Element.XmlElementNode;
        }

        private string _ID;
        [CategoryAttribute("Properties"), DescriptionAttribute("Content type ID"), RefreshProperties(RefreshProperties.None), ReadOnly(false), Editor(typeof(IDSelector), typeof(UITypeEditor))]
        public string ID
        {
            get { return _ID; }
            set
            {
                _ID = value;

                string key = "ContentType_" + _ID;
                if (key != this.ElementInfo.Key)
                {
                    this.ElementInfo.Manager.RemoveClassesInfoByKey(this.ElementInfo.Key);
                    
                    if (!string.IsNullOrEmpty(_ID))
                        this.ElementInfo.Key = key;
                }
            }
        }

        [CategoryAttribute("Properties"), DescriptionAttribute("Content type name"), RefreshProperties(RefreshProperties.None), TypeConverter(typeof(ResourceExpandableObjectConverter))]
        public ResourceStringContainer Name
        {
            get;
            set;
        }

        [CategoryAttribute("Properties"), DescriptionAttribute("Group name"), RefreshProperties(RefreshProperties.None), TypeConverter(typeof(ResourceExpandableObjectConverter))]
        public ResourceStringContainer Group
        {
            get;
            set;
        }

        [CategoryAttribute("Properties"), DescriptionAttribute("Description"), RefreshProperties(RefreshProperties.None), TypeConverter(typeof(ResourceExpandableObjectConverter))]
        public ResourceStringContainer Description
        {
            get;
            set;
        }

        [CategoryAttribute("EventReceivers"), Browsable(true), DisplayName("Attached event receiver classes"), DescriptionAttribute("Classes in project that will automatically generate event receiver registrations for this element."), ReadOnly(false), TypeConverter(typeof(CodeClassCollectionTypeConverter)), Editor(typeof(EventClassCollectionEditor), typeof(UITypeEditor))]
        public List<CodeClass> EventReceiverClasses
        {
            get;
            set;
        }

        [CategoryAttribute("EventReceivers"), Browsable(true), DisplayName("Event registrations"), DescriptionAttribute("Event registrations"), ReadOnly(false), TypeConverter(typeof(EventReceiverCollectionTypeConverter)), Editor(typeof(EventReceiverCollectionEditor), typeof(UITypeEditor))]
        public List<EventReceiverInfo> EventRegistrations
        {
            get;
            set;
        }

        public override string ToString()
        {
            string s = this.Name.GetValue(null);
            if (string.IsNullOrEmpty(s))
            {
                s = this.ID;
                if (string.IsNullOrEmpty(s))
                    s = this.ElementInfo.ElementName; // +this.ElementInfo.ID.ToString();
            }

            return "<ContentType> " + s;
        }

        public void SetNewSheetFlag(bool IsNewSheet)
        {
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this.GetType())["ElementFileName"];
            BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
            FieldInfo isBrowsable = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
            isBrowsable.SetValue(attrib, IsNewSheet);            
        }

        public void InvokeIDSelector(int UIType)
        {
            IDSelector obj = new IDSelector();
            string ret = obj.ShowUI(this.Project, UIType);

            if (string.IsNullOrEmpty(ret))
                return;

            this.ID = ret;
        }

        public class IDSelector : UITypeEditor
        {
            public IDSelector()
                : base()
            {
            }

            public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
            {
                return UITypeEditorEditStyle.Modal;
            }
            public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
            {
                string ret = value as string;

                IPropertySheet sheet = context.Instance as IPropertySheet;

                using (DialogNewContentTypeDef form = new DialogNewContentTypeDef())
                {
                    DialogResult res = form.ShowDialog();
                    if (res != DialogResult.OK)
                        return ret;

                    if (form.rdoInheritFromBuiltin.Checked)
                    {
                        ret = ShowUI(sheet.Project, 1);
                    }
                    else if (form.rdoInheritFromExistent.Checked)
                    {
                        ret = ShowUI(sheet.Project, 2);
                    }
                    else if (form.rdoAppendGUID.Checked)
                    {
                        ret = ShowUI(sheet.Project, 3);
                    }
                }


                return ret;
            }

            public string ShowUI(SpecialProject project, int UIType)
            {
                string ret = null;

                if (UIType == 1)
                {
                    using (DialogNewContentTypeFromBuiltIn form_builtin = new DialogNewContentTypeFromBuiltIn())
                    {
                        form_builtin.cboContentTypes.Items.Clear();
                        form_builtin.cboContentTypes.Sorted = true;
                        form_builtin.cboContentTypes.DisplayMember = "Key";
                        form_builtin.cboContentTypes.ValueMember = "Value";

                        XmlDocument xmldoc = new XmlDocument();
                        xmldoc.LoadXml(project.ServiceProxy.GetAllBuiltInContentTypes());


                        if (xmldoc.DocumentElement == null)
                        {
                            throw new Exception("No content types found.");
                        }

                        foreach (XmlNode node in xmldoc.DocumentElement.ChildNodes)
                        {
                            XmlElement el = node as XmlElement;
                            if (el == null)
                                continue;

                            KeyValuePair<string, string> kvp = new KeyValuePair<string, string>(el.GetAttribute("Name"), el.GetAttribute("Id"));
                            form_builtin.cboContentTypes.Items.Add(kvp);
                        }


                        form_builtin.cboContentTypes.SelectedIndex = 0;

                        DialogResult res = form_builtin.ShowDialog();

                        if (res == DialogResult.OK && form_builtin.cboContentTypes.SelectedIndex != -1)
                        {
                            KeyValuePair<string, string> sel_kvp = (KeyValuePair<string, string>)form_builtin.cboContentTypes.SelectedItem;

                            if (form_builtin.chkOnlyAsParent.Checked)
                                ret = sel_kvp.Value;
                            else
                                ret = sel_kvp.Value + "00" + Guid.NewGuid().ToString("N").ToUpper();
                        }
                    }
                }

                else if (UIType == 2)
                {
                    using (DialogSharePointExplorer explorer = new DialogSharePointExplorer())
                    {
                        explorer.SPExplorer.ShowContentTypeGroups = true;
                        explorer.SPExplorer.ShowContentTypes = true;
                        explorer.SPExplorer.ShowFeatures = false;
                        explorer.SPExplorer.ShowFields = false;
                        explorer.SPExplorer.ShowSolutions = false;
                        explorer.SPExplorer.ShowLists = false;

                        explorer.Message = "Pick a content type to inherit from.";
                        explorer.CurrentProject = project;

                        explorer.SPExplorer.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
                        explorer.SPExplorer.Margin = new Padding(0, 0, 0, 15);

                        CheckBox chkOnlyAsParent = new CheckBox();
                        chkOnlyAsParent.AutoSize = true;
                        chkOnlyAsParent.Location = new System.Drawing.Point(230, explorer.Height - 64);
                        chkOnlyAsParent.Name = "chkOnlyAsParent";
                        chkOnlyAsParent.Size = new System.Drawing.Size(108, 17);
                        chkOnlyAsParent.Margin = new Padding(0, 5, 0, 5);
                        chkOnlyAsParent.Text = "Only as parent ID";
                        chkOnlyAsParent.UseVisualStyleBackColor = true;
                        chkOnlyAsParent.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

                        explorer.Controls.Add(chkOnlyAsParent);

                        explorer.MinimumSize = new System.Drawing.Size(explorer.Width, explorer.Height);
                        DialogResult result = explorer.ShowDialog();
                        if (result != DialogResult.OK)
                            return ret;

                        string ct_id = explorer.SelectedContentTypeId;
                        if (ct_id != null)
                        {
                            if (!chkOnlyAsParent.Checked)
                                ret = ct_id + "00" + Guid.NewGuid().ToString("N").ToUpper();
                            else
                                ret = ct_id + "00";
                        }
                    }
                }
                else if (UIType == 3)
                {
                    if (string.IsNullOrEmpty(ret))
                        ret = "0x01";

                    ret += "00" + Guid.NewGuid().ToString("N").ToUpper();
                }


                return ret;
            }
        }
    }

}
